﻿/*
 * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
 */

#ifndef BURNCTRLMCU_H
#define BURNCTRLMCU_H
#include "BurnCtrl.h"

#pragma pack(push)
#pragma pack(1)

namespace BurnToolSpace {
struct FileHead {
    unsigned char name[32];                               /* image name to show, len 32 */
    unsigned long startIndex;                             /* image start index in whole file */
    unsigned long imageSize;                              /* image size */
    unsigned long burnAddr;                               /* burn addr in flash, like burn 0 200000, equal 0 */
    unsigned long burnSize;                               /* burn size in burn cmd, like burn 0 200000, equal 200000,
                                                          * this size maybe bigger than imageSize */
   // FileType type;                                       /* file type */
};
using FileInfo = FileHead;

/**
* @brief the allinone.bin file head info
*/
struct FwpkgAllinone {
    unsigned long flag;                                   /* a flag 0xefbeaddf */
    unsigned short crc;                                   /* from imageNum to head end */
    unsigned short imageNum;                              /* image count */
    unsigned long totalFileSize;                          /* file size */
    FileInfo info[0];
};
using FwpkgHead = FwpkgAllinone;

struct ChipIdAttrStruct {
    uint chipId;
    char chipInfoSize;
};
using ChipIdAttr = ChipIdAttrStruct;
#pragma pack(pop)

class BurnCtrlMcu : public BurnCtrl {
    Q_OBJECT
public:
    explicit BurnCtrlMcu(ChipType type, QObject *parent = nullptr);
    void StartConnect() override;
    void McuReopen() override;
    U32 StartBurn() override;
    void SetLoaderInfo(QString mLoaderFile, int mLoaderSize) override;
    void SetTotalDigits(int mTotalDigits) override;
    void SetParamStartAddress(ulong mParameterStartAddress) override;
    void SetProtectionPara(ParameterInfo mInfo) override;

protected slots:
    void SlotExport(WPARAM data, LPARAM len) override;
    void SlotEraseMemory(WPARAM data, LPARAM len) override;
    void SlotGetParameter() override;
    void SlotSetParameter() override;
    bool UnprotectParameterArea();
protected:
    bool OpenDevice();
    bool PartOfOpenDevice(int chipModeData);
    void ShowConnectionSuggestions();
    bool InitJtagTransport();
    bool InitInterfaceFile(QString &interfaceFile);
    bool InitTargetFile(QString &targetFile);
    bool IsFirstSeriesChip(int chipMode) const;
    bool GetChipIdFun();
    int OnlyReadFile(QString szFile, QByteArray &data) const;
    bool ReadFileShowLog(int code, QString filePath);
    int GetChipId(BYTE *recevie, int recvLen) const;
    void CloseDevice(bool isConnectState, bool isUIState);
    bool GetFileInfo(QString fileName, DWORD &burnAddress, DWORD fileIndex, DWORD fileSize);
    void InitBurnCmdByArray(const QMap<int, BIN_INFO> &infoArray) override;
//    void InitBurnCmd() override;
    bool CheckFlashAddressLegitimacy(DWORD address, DWORD size,
        DWORD baseAddress, DWORD maxSize) const;
    void StartBurnImage(QString fileName, DWORD burnAddress, DWORD fileSize);
    bool DownloadFile(QString fileName, DWORD burnAddress, DWORD burnSize);
    bool BurnLoadTarget(QString fileName, DWORD burnAddress, DWORD burnSize);
    static void SetTextEditReceivePrint(long long handle, const char* comNum,
                                             const char* szInfo, const char* deBugszInfo, BOOL flag);
    static void SetProgress(long long handle, int progress);
    static void SetProgressPart(BurnCtrlMcu *&mcu, double &pro, int progress);
    static int CancelBurn();
    bool Burnload(QString loadFilePath, DWORD burnAddress);
    bool BurnTarget(QString fileName, DWORD burnAddress, DWORD burnSize);
    int Erase(unsigned long long address, int length);
    bool CheckFile(DWORD burnAddress, DWORD burnSize);
    bool VerifyImage(DWORD burnAddress, DWORD burnSize);
    int Go(unsigned long long address) const;
    bool RunTarget(DWORD burnAddress);
    int ResetDrvice() const;
    void ResetUIAndFSM() override;
    bool GetParameterInfoList();
    void SetIsInfoPart(bool isPart) override;
    void SetInfoArea(int infoArea) override;
    void SetParameterInfoList(const QList<ParameterInfo> &mParameterInfoList,
                              const QList<ParameterInfo> &mInfoUnlockList,
                              const QList<ParameterBuff> &mMapBuf) override;
    void SetParameterSaveInfo(const QString &mParameterFilePath, ulong mEraseBaseNum) override;
    void SetIsParameterReset(bool isReset) override;
    int Unprotected() const;
    bool ReOpen();
    bool StartSetParameter();
    int GetParameterData();
    bool DirectSetParameter();
    bool Islock() const;
    bool IsUnlockInfo();
    bool BurnFile(QString filePath, DWORD address, int length) const;
    bool SaveParameterWhenUnlock();
    bool SetParameterWhenUnlock();
    void BurnCtrlCancel() override;
    void BurnFileFailed();
    DWORD ReadFlashData(DWORD readAddress, int readSize, QString readFilePath);
    bool GetFileData(QByteArray &data, BIN_INFO &binInfo,
        const char *pBurnFile, DWORD fileLen) const;
    void SetResult(unsigned int result) override;

private:
    unsigned long long deviceHander;
    bool isWriteInfo;
    ChipIdAttr chipIdAttr;
    bool isAllinone;
    BIN_INFO eflashfile;
    BIN_INFO loadfile;
    QByteArray info;
    static QMap<unsigned long long, BurnCtrlMcu *> myCtrlMap;
    QString loaderFile;
    unsigned int loaderSize;
    int totalDigits;
    ulong parameterStartAddress;
    QByteArray chipParameterList;
    ParameterInfo protectionPara;
    bool isInfoPart;
    int iInfoArea;
    QList<ParameterInfo> parameterInfoList;
    QList<ParameterInfo> infoUnlockList;
    QList<ParameterBuff> mapBuf;
    QString parameterFilePath;
    ulong eraseBaseNum;
    bool isParameterReset = false;
    QMutex *mutex;
    int progressCount = 0;
};
}

#endif // BURNCTRLMCU_H
